import sys
import aggregator
import shlex
import os.path
import readline

from backends.support import ResourceCategory, ResourceRawHTML, Quiz, ResourcePlain, ResourceLink
from cmd import Cmd

history_file = os.path.expanduser("~/.polyglot_history")

class PolyglotCmd(Cmd):
    def do_authenticate(self, args):
        """Authenticates with a backend. Args: backend, username, password, school"""
        args = shlex.split(args)

        if len(args) != 4:
            print("Wrong number of args")
            return

        name = args[0]
        self.backend = aggregator.load_backend(name)

        config = {
            "Email": args[1],
            "Username": args[1],
            "Password": args[2],
            "School": args[3]
        }

        if aggregator.authenticate(self.backend, config):
            print("OK")
        else:
            print("Authentication failed")
            return

        course_set = self.backend.courses

        self.courses = {}

        for course in course_set:
            print(course.title)
            self.courses[course.title] = course

    def dump_resource(self, rsrc, expand):
        if isinstance(rsrc, ResourceCategory):
            print(rsrc.name)

            if expand:
                for child in rsrc.children:
                    print("..." + child.name)

                for child in rsrc.contents:
                    print("")
                    self.dump_resource(child, False)

        elif isinstance(rsrc, ResourceRawHTML):
            print(rsrc.name + ": " + rsrc.html)
        elif isinstance(rsrc, ResourcePlain):
            print(rsrc.name + ": " + rsrc.text)
        elif isinstance(rsrc, ResourceLink):
            print(rsrc.name + ": " + rsrc.url)
        else:
            print(rsrc.name + " (" + type(rsrc).__name__ + ")")

    def find_resource(self, root, path):
        if len(path) == 0:
            return root

        if isinstance(root, ResourceCategory):
            for child in root.children:
                if child.name == path[0]:
                    return self.find_resource(child, path[1:])

            print("Can't find " + path[0])
            return

        print("Wrong rsrc type with " + ",".join(path))

    def find_content(self, head, name):
        for c in head.contents:
            if c.name == name:
                return c

        print("Can't find content")

    def do_resources(self, args):
        args = shlex.split(args) 

        if len(args) == 0:
            print("Must specify course")
            return

        self.dump_resource(self.find_resource(self.courses[args[0]].resources, args[1:]), True)

    def do_grades(self, args):
        args = shlex.split(args) 

        if len(args) == 0:
            for course in self.backend.courses:
                try:
                    print(course.title + ": " + str(course.grade_summary * 100) + "%")
                except AttributeError:
                    print(course.title + ": (N/A)")
        else:
            course = self.courses[args[0]]

            try:
                for category in course.grades:
                    print(category.name + " (" + str(category.weight * 100) + "%):")

                    for grade in category.grades:
                        print(" - " + grade.name + ": " + ((str(grade.grade * 100)) if grade.grade else "(N/A) ") + "%")
            except IOError:
                print("N/A")

    def tasks(self, course):
        try:
            for task in course.tasks:
                print("- " + task.name)
        except AttributeError:
            print("(tasks N/A)")

    def find_task(self, lst, name):
        for task in lst:
            if task.name == name:
                return task

    def do_tasks(self, args):
        args = shlex.split(args)

        if len(args) == 0:
            for course in self.backend.courses:
                print(course.title + ":")
                self.tasks(course)
                print()
        elif len(args) == 1:
            self.tasks(self.courses[args[0]])
        elif len(args) == 2:
            task = self.find_task(self.courses[args[0]].tasks, args[1])

            if task is None:
                print("Task not found")
                return

            print(task.name)
            print(task.due_date)

            rsrcs = task.resources

            if rsrcs is not None:
                for rsrc in rsrcs:
                    self.dump_resource(rsrc, True)
            else:
                print("No resources")

    def do_wget(self, args):
        """
        Download file using loaded backend's session.
        Useful for ./export-gdoc, etc.
        """

        args = shlex.split(args) 

        if len(args) == 0:
            print("Must include URL")
            return

        u = self.backend.session.get(args[0])
        with open(args[1] if len(args) > 1 else "download.bin", "wb") as f:
            f.write(u.content)

    def do_curl(self, url):
        """
        Dump file using loaded backend's session.
        """

        print(self.backend.session.get(url).text)

    def find_specific(self, args, t):
        args = shlex.split(args) 

        if len(args) == 0:
            print("Must specify course")
            return

        head = self.find_resource(self.courses[args[0]].resources, args[1:-1])
        r = self.find_content(head, args[-1])

        if r is None:
            return None

        if not isinstance(r, t):
            print("Requested resource is not a " + t.__name__)
            return None

        return r

    def do_quiz(self, args):
        self.quiz = self.find_specific(args, Quiz)
        self.questions = quiz.questions()
        self.quiz_ptr = -1

        if self.questions is not None:
            print("Quiz loaded with " + len(self.questions) + "questions")
            print("Use quiznext or quizseek to begin. quizsubmit once done.")
        else:
            print("Questions not loaded")

    def do_quiznext(self):
        self.quiz_ptr = self.quiz_ptr + 1
        self.quiz_question(self.questions[self.quiz_ptr])

    def do_quizseek(self, args):
        self.quiz_ptr = int(args)
        self.quiz_question(self.questions[self.quiz_ptr])

    def do_quizsubmit(self):
        self.quiz.submit(self.questions)

    def do_quit(self, _):
        """Quits polyglot"""
        sys.exit(0)

    def preloop(self):
        try:
            readline.read_history_file(history_file)
        except IOError:
            pass 

    def postcmd(self, _1, _2):
        readline.write_history_file(history_file)

prompt = PolyglotCmd()
prompt.prompt = "> "
prompt.cmdloop()
